using System;
using System.Drawing;

namespace NobleTech.Products.CreatureKingdom.Utils
{
    public struct PointD
    {
        public double X, Y;

        public PointD(double X, double Y)
        {
            this.X = X;
            this.Y = Y;
        }

        public static explicit operator PointF(PointD pt)
        {
            return new PointF((float)pt.X, (float)pt.Y);
        }

        public static implicit operator PointD(PointF pt)
        {
            return new PointF(pt.X, pt.Y);
        }

        public override string ToString()
        {
            return string.Format("({0}, {1})", X, Y);
        }

        public override int GetHashCode()
        {
            return X.GetHashCode() ^ Y.GetHashCode();
        }

        public override bool Equals(object obj)
        {
            if (obj is PointD)
                return this == (PointD)obj;
            return ((PointF)this).Equals(obj);
        }

        public static PointD operator +(PointD pt, SizeD size)
        {
            return new PointD(pt.X + size.Width, pt.Y + size.Height);
        }

        public static PointD operator -(PointD pt, SizeD size)
        {
            return new PointD(pt.X - size.Width, pt.Y - size.Height);
        }

        public static SizeD operator -(PointD pt1, PointD pt2)
        {
            return new SizeD(pt1.X - pt2.X, pt1.Y - pt2.Y);
        }

        public static bool operator ==(PointD a, PointD b)
        {
            return Misc.CmpDbl(a.X, b.X) && Misc.CmpDbl(a.Y, b.Y);
        }

        public static bool operator !=(PointD a, PointD b) { return !(a == b); }

        public static bool operator <(PointD pt1, PointD pt2)
        {
            return pt1.X < pt2.X && pt1.Y < pt2.Y;
        }

        public static bool operator >(PointD pt1, PointD pt2)
        {
            return pt1.X > pt2.X && pt1.Y > pt2.Y;
        }

        public static bool operator <=(PointD pt1, PointD pt2)
        {
            return pt1.X <= pt2.X && pt1.Y <= pt2.Y;
        }

        public static bool operator >=(PointD pt1, PointD pt2)
        {
            return pt1.X >= pt2.X && pt1.Y >= pt2.Y;
        }

        public static PointD Min(PointD pt1, PointD pt2)
        {
            return new PointD(Math.Min(pt1.X, pt2.X), Math.Min(pt1.Y, pt2.Y));
        }

        public static PointD Max(PointD pt1, PointD pt2)
        {
            return new PointD(Math.Max(pt1.X, pt2.X), Math.Max(pt1.Y, pt2.Y));
        }
    }
}
